<?php


namespace app\system\service;

class FileService
{
	public static function upload_image($options)
	{
		$save_dir = "uploads/images/system_image";
		try {
			if (!file_exists($save_dir)) {
				mkdir($save_dir, 509, true);
			}
			$file = request()->file("file");
			$info = $file->validate(["ext" => "jpg,png,gif,jpeg,bmp"])->move($save_dir);
			if (empty($info)) {
				throw new \think\Exception($file->getError());
			}
			$data = array_merge(["name" => $file->getInfo("name"), "type" => \app\common\model\File::type_image, "create_time" => time(), "cid" => $options["cid"]], handle_file_storage($file, $info, $save_dir));
			$id = \think\Db::name("system_file")->insert($data);
			return ["code" => \app\system\model\Code::success, "msg" => "上传成功", "data" => $id];
		} catch (\think\Exception $e) {
			$messge = $e->getMessage();
			return ["code" => \app\system\model\Code::error, "msg" => "上传文件失败:" . $messge];
		}
	}
	public static function get_image_list($options)
	{
		$where = [];
		if (!empty($options["type"])) {
			$where["type"] = $options["type"];
		}
		if (!empty($options["cid"]) && $options["cid"] != 0) {
			$where[] = ["cid", "=", $options["cid"]];
		}
		if (!empty($options["name"])) {
			$where[] = ["name", "like", "%{$options["name"]}%"];
		}
		$siteurl = getsiteurl() . "/";
		$count = \think\Db::name("system_file")->where($where)->count();
		$pages = ceil($count / $options["limit"]);
		$lists = \think\Db::name("system_file")->field(["name", "uri as path", "CONCAT('{$siteurl}',uri) as uri", "id", "cid", "channel", "url"])->where($where)->page($options["page"], $options["limit"])->order(["id" => "desc"])->select();
		$data = [];
		foreach ($lists as $file_item) {
			if (empty($file_item["channel"])) {
				$file_item["address"] = $siteurl . "index/system/get_custom_image/name/" . base64_encode($file_item["path"]);
			} else {
				$file_item["address"] = $file_item["url"];
			}
			if ($file_item["cid"] == 0) {
				$file_item["category_name"] = "默认分类";
			} else {
				$file_item["category_name"] = \think\Db::name("system_file_classify")->where(["id" => $file_item["cid"]])->value("name");
			}
			$data[] = $file_item;
		}
		return ["code" => \app\system\model\Code::success, "data" => $data, "count" => $count, "pages" => $pages];
	}
	public static function del_image($options)
	{
		\think\Db::startTrans();
		try {
			$uri = \think\Db::name("system_file")->where("id", "in", $options["ids"])->column("uri");
			$res = \think\Db::name("system_file")->where("id", "in", $options["ids"])->delete();
			foreach ($uri as $path) {
				if (is_file($path)) {
					unlink($path);
				}
			}
			\think\Db::commit();
			return ["code" => \app\system\model\Code::success, "data" => $res];
		} catch (\Exception $e) {
			\think\Db::rollback();
			return ["code" => \app\system\model\Code::error, "msg" => $e->getMessage()];
		}
	}
	public static function get_classify_list($options = [])
	{
		$lists = \think\Db::name("system_file_classify")->field(["id", "name", "pid", "level", "sort", "create_time", "update_time"])->order(["sort" => "desc"])->select();
		$data = linear_to_tree($lists, "children");
		return $data;
	}
	public static function get_classify_info($options)
	{
		$data = \think\Db::name("system_file_classify")->where(["id" => $options["id"]])->field(["id", "name", "pid", "level", "sort", "create_time", "update_time"])->find();
		if (empty($data)) {
			return ["code" => \app\system\model\Code::fail, "msg" => "ID不存在"];
		}
		return ["code" => \app\system\model\Code::success, "data" => $data];
	}
	public static function add_classify($options)
	{
		\think\Db::startTrans();
		try {
			$cate = \think\Db::name("system_file_classify")->where("id", "=", $options["pid"])->find();
			if ($cate) {
				if ($cate["level"] >= 2) {
					return ["code" => \app\system\model\Code::fail, "msg" => "仅能添加二级分类"];
				}
			}
			$level = 0;
			if ($options["pid"]) {
				$level = \think\Db::name("system_file_classify")->where(["id" => $options["pid"]])->value("level");
			}
			$data = ["name" => $options["name"], "pid" => $options["pid"], "sort" => $options["sort"], "level" => $level + 1, "create_time" => time()];
			\think\Db::name("system_file_classify")->insert($data);
			\think\Db::commit();
			return ["code" => \app\system\model\Code::success];
		} catch (\Exception $e) {
			\think\Db::rollback();
			return ["code" => \app\system\model\Code::error, "msg" => $e->getMessage()];
		}
	}
	public static function edit_classify($options)
	{
		\think\Db::startTrans();
		try {
			$item = \think\Db::name("system_file_classify")->where(["id" => $options["id"]])->find();
			if (empty($item)) {
				return ["code" => \app\system\model\Code::fail, "msg" => "分类不存在"];
			}
			if ($options["id"] == $options["pid"]) {
				return ["code" => \app\system\model\Code::fail, "msg" => "上级分类不能是自己"];
			}
			$level = 0;
			$data = ["pid" => $options["pid"], "name" => $options["name"], "sort" => $options["sort"], "update_time" => time()];
			$data["level"] = $level + 1;
			if ($options["pid"] != 0) {
				$maxLevel = 2;
				$partner = \think\Db::name("system_file_classify")->where(["id" => $options["pid"]])->find();
				if (empty($partner)) {
					return ["code" => \app\system\model\Code::fail, "msg" => "父级分类不存在"];
				}
				$data["level"] = $partner["level"] + 1;
				if ($item["pid"] != $options["pid"] && $maxLevel < $data["level"]) {
					return ["code" => \app\system\model\Code::fail, "msg" => "移动分类失败，仅能添加{$maxLevel}级分类"];
				}
				$queryLastChildrenLevel = self::queryLastChildrenLevel($item["id"], $data["level"]);
				if ($item["pid"] != $options["pid"] && !empty($queryLastChildrenLevel) && $maxLevel < max($queryLastChildrenLevel)) {
					return ["code" => \app\system\model\Code::fail, "msg" => "移动分类失败,仅能添加{$maxLevel}级分类(移动后当前分类为{$data["level"]}级,算上所有子级分类已是" . max($queryLastChildrenLevel) . "级)"];
				}
			}
			\think\Db::name("system_file_classify")->where("id", $options["id"])->update($data);
			self::updateChildrenLevel($item["id"], $data["level"]);
			\think\Db::commit();
			return ["code" => \app\system\model\Code::success];
		} catch (\Exception $e) {
			\think\Db::rollback();
			return ["code" => \app\system\model\Code::error, "msg" => $e->getMessage()];
		}
	}
	public static function updateChildrenLevel($id, $selfLevel = 1)
	{
		$children = \think\Db::name("system_file_classify")->where(["pid" => $id])->select();
		foreach ($children as $item) {
			\think\Db::name("system_file_classify")->where("id", $item["id"])->update(["level" => $selfLevel + 1]);
			self::updateChildrenLevel($item["id"], $selfLevel + 1);
		}
	}
	public static function queryLastChildrenLevel($id, $selfLevel = 1, $levels = [])
	{
		$children = \think\Db::name("system_file_classify")->where(["pid" => $id])->select();
		foreach ($children as $item) {
			$levels[] = $selfLevel + 1;
			array_merge($levels, self::queryLastChildrenLevel($item["id"], $selfLevel + 1, $levels));
		}
		return array_unique($levels);
	}
	public static function del_classify($options)
	{
		\think\Db::startTrans();
		try {
			$item = \think\Db::name("system_file_classify")->where(["id" => $options["id"]])->find();
			if (empty($item)) {
				return ["code" => \app\system\model\Code::fail, "msg" => "分类不存在"];
			}
			$child = \think\Db::name("system_file_classify")->where(["pid" => $options["id"]])->find();
			if ($child) {
				return ["code" => \app\system\model\Code::fail, "msg" => "当前分类下有子分类,请先调整该分类下的子分类"];
			}
			\think\Db::name("system_file_classify")->where(["id" => $options["id"]])->delete();
			$image_ids = \think\Db::name("system_file")->where(["cid" => $options["id"]])->column("id");
			\think\Db::commit();
			return ["code" => \app\system\model\Code::success];
		} catch (\Exception $e) {
			\think\Db::rollback();
			return ["code" => \app\system\model\Code::error, "msg" => $e->getMessage()];
		}
	}
	public static function get_classify_choose($options = [])
	{
		$lists = \think\Db::name("system_file_classify")->field(["id", "pid", "name"])->select();
		$data = multilevel_linear_sort($lists, "|-");
		return $data;
	}
}